;; The first four lines of this file were added by Dracula.
;; They tell DrScheme that this is a Dracula Modular ACL2 program.
;; Leave these lines unchanged so that DrScheme can properly load this file.
#reader(planet "reader.rkt" ("cce" "dracula.plt") "modular" "lang")
(require "ihuechange.lisp")
(require "mbmptree.lisp")
(require "mhelpers.lisp")

(module Mhuechange
  (import Ihelpers)
  (import IbmpTree)
  
  ; Convert one pixel's RGB values to the given hue
  ; pre: col - column number
  ;      r   - red [0, 255]
  ;      g   - green [0, 255]
  ;      b   - blue [0, 255]
  ;      h   - hue [0, 360]
  ; post: list containing the column number and the new red,
  ;       green, blue values after being changed to the given hue|
  (defun pixel-to-hue (col r g b h)
    (if (and (<= r 255) (>= r 0)
             (<= g 255) (>= g 0)
             (<= b 255) (>= b 0)
             (<= h 360) (>= h 0))
        (let* ((hsv (RGB-to-HSV r g b))
               (s   (cadr hsv))
               (v   (caddr hsv)))
          (if (and (= s 0) (< v 245))
              (cons col (HSV-to-RGB h .5 v))
              (cons col (HSV-to-RGB h s v))))
        "Invalid RGB value."))
  
  ; Convert one pixel's RGB values to the given hue (column not included)
  ; This function is used in the hipstafy module.
  ; pre: r   - red [0, 255]
  ;      g   - green [0, 255]
  ;      b   - blue [0, 255]
  ;      h   - hue [0, 360]
  ; post: list containing the column number and the new red,
  ;       green, blue values after being changed to the given hue|
  (defun pixel-to-hue-original (r g b h)
    (if (and (<= r 255) (>= r 0)
             (<= g 255) (>= g 0)
             (<= b 255) (>= b 0)
             (<= h 360) (>= h 0))
        (let* ((hsv (RGB-to-HSV r g b))
               (s   (cadr hsv))
               (v   (caddr hsv)))
          (HSV-to-RGB h s v))
        "Invalid RGB value."))
  
  ; Converts each value in a row to the specified hue
  ; pre: row - list of column values of a row from the bitmap tree
  ;  columns - list of modified columns values to be returned
  ;      hue - [0, 360]
  ; post: list containing the each modified column in the row
  ;       where a column is a list of the column number and its
  ;       new red, green, blue values in greyscale
  (defun make-hue-columns (row columns hue)
    (if (consp row)
        (let* ((col    (car row))
               (colNum (car col))
               (r      (cadr col))
               (g      (caddr col))
               (b      (cadddr col)))
          (make-hue-columns (cdr row) (cons (pixel-to-hue colNum r g b hue) columns) hue))
        columns))
  
  ; Converts the given tree to the specified hue.
  ; pre:    tr - bitmap tree
  ;        hue - [0, 360]
  ;   rowIndex - current row index, used for looping
  ;    numRows - total number of rows in the tree
  ; post: tree containing new values corresponding to the given hue
  (defun hue-change-helper (tr hue rowIndex numRows)
    (if (< rowIndex numRows)
        (let* ((row (get-row tr rowIndex)))
          (hue-change-helper (insert-row tr rowIndex (make-hue-columns row nil hue))
                             hue (+ rowIndex 1) numRows))
        tr))
  
  ; Converts the tree to the specified hue using the hue-change-helper function.
  ; pre: tr - bitmap tree
  ;     hue - number specifying which hue to change the image to [0, 360]
  ; post: tree containing new values corresponding to the given hue
  (defun hue-change (tr hue)
    (let* ((numRows (car (get-dimensions tr))))
      (hue-change-helper tr hue 0 numRows)))
  
  (export Ihuechange))